package cn.turing.firecontrol.admin.biz;

import cn.turing.firecontrol.admin.entity.BackChunk;
import cn.turing.firecontrol.admin.entity.BackFilelist;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

/**
 * @Description:
 * @author：dingchenxi
 * @date: 2022/06/21 22:44
 */
@Slf4j
@Service
public class UploadBiz {


    @Transactional(rollbackFor = Exception.class)
    public int postFileUpload(BackChunk chunk, HttpServletResponse response) {
        int result = 0;
        MultipartFile file = chunk.getFile();
        log.debug("file originName: {}, chunkNumber: {}", file.getOriginalFilename(), chunk.getChunkNumber());
        Path path = Paths.get(generatePath(filePath + folderPath, chunk));
        try {
            Files.write(path, chunk.getFile().getBytes());
            log.debug("文件 {} 写入成功, md5:{}", chunk.getFilename(), chunk.getIdentifier());
            //写入数据库
        } catch (IOException e) {
            e.printStackTrace();
            response.setStatus(507);
            return 0;
        }
        return result;
    }

    public int mergeFile(BackFilelist fileInfo) {
        String filename = fileInfo.getFilename();
        String file = filePath + folderPath + "/" + fileInfo.getIdentifier() + "/" + filename;
        String folder = filePath + folderPath + "/" + fileInfo.getIdentifier();
        String url = folderPath + "/" + fileInfo.getIdentifier() + "/" + filename;
        System.out.println(file+"---"+folder);
        merge(file, folder, filename);
        /*//当前文件已存在数据库中时,返回已存在标识
        if (backFilelistMapper.selectSingleBackFilelist(fileInfo) > 0) {
            return CommonConstant.UPDATE_EXISTS;
        }
        fileInfo.setLocation(file);
        fileInfo.setUrl(url);
        int i = backFilelistMapper.insertBackFilelist(fileInfo);
        if (i > 0) {
            //插入文件记录成功后,删除chunk表中的对应记录,释放空间
            BackChunk backChunk = new BackChunk();
            backChunk.setIdentifier(fileInfo.getIdentifier());
            backChunk.setFilename(fileInfo.getFilename());
            backChunkMapper.deleteBackChunkByIdentifier(backChunk);
        }*/
        return 0;
    }

    /**
     * 功能描述:生成块文件所在地址
     *
     * @param:
     * @return:
     * @author: xjd
     * @date: 2020/7/28 16:10
     */
    private String generatePath(String uploadFolder, BackChunk chunk) {
        StringBuilder sb = new StringBuilder();
        //文件夹地址/md5
        sb.append(uploadFolder).append("/").append(chunk.getIdentifier());
        //判断uploadFolder/identifier 路径是否存在，不存在则创建
        if (!Files.isWritable(Paths.get(sb.toString()))) {
            log.info("path not exist,create path: {}", sb.toString());
            try {
                Files.createDirectories(Paths.get(sb.toString()));
            } catch (IOException e) {
                log.error(e.getMessage(), e);
            }
        }

        //文件夹地址/md5/文件名-1
        return sb.append("/")
                .append(chunk.getFilename())
                .append("-")
                .append(chunk.getChunkNumber()).toString();
    }

    /**
     * 文件合并
     *
     * @param targetFile 要形成的文件名
     * @param folder     要形成的文件夹地址
     * @param filename   文件的名称
     */
    public static void merge(String targetFile, String folder, String filename) {
        try {
            Files.createFile(Paths.get(targetFile));
            Files.list(Paths.get(folder))
                    .filter(path -> !path.getFileName().toString().equals(filename))
                    .sorted((o1, o2) -> {
                        String p1 = o1.getFileName().toString();
                        String p2 = o2.getFileName().toString();
                        int i1 = p1.lastIndexOf("-");
                        int i2 = p2.lastIndexOf("-");
                        return Integer.valueOf(p2.substring(i2)).compareTo(Integer.valueOf(p1.substring(i1)));
                    })
                    .forEach(path -> {
                        try {
                            //以追加的形式写入文件
                            Files.write(Paths.get(targetFile), Files.readAllBytes(path), StandardOpenOption.APPEND);
                            //合并后删除该块
                            Files.delete(path);
                        } catch (IOException e) {
                            log.error(e.getMessage(), e);
                        }
                    });
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
    }



    private String filePath="D:/pic";

    private final static String folderPath = "/file";
}
